<template>
  <div v-if="$slots.default" class="x-landing-live">
    <slot />
  </div>
  <x-drawer v-model:visible="liveVisible" :title="drawerTitle" width="800px" @update:show="handleCancel">
    <x-form
      ref="formRef"
      v-model:model="formData"
      :rules="rules"
      :label-width="100"
      label-placement="left"
      size="small"
    >
      <n-form-item label="视频号ID" path="channelsId">
        <n-space :size="3" vertical style="width: 100%">
          <n-input
            v-model:value="formData.channelsId"
            placeholder="请输入视频号ID，以“sph”开头的id，可在视频号助手获取"
            maxlength="255"
            clearable
          />
          <n-text depth="3">注意：视频号必须与小程序相同主体，否则跳转至备用链接。</n-text>
          <n-a type="info" href="https://doc.weixin.qq.com/doc/w3_AEYALQbmAEsc9W3N35ORIutPFMRNH" target="_blank">
            如何获取视频号ID?
          </n-a>
        </n-space>
      </n-form-item>
      <n-form-item v-if="isRequireLinkContent" :label="linkContentName" path="linkContent">
        <n-input v-model:value="formData.linkContent" :placeholder="placeholderName" maxlength="255" clearable />
      </n-form-item>
      <n-form-item :show-require-mark="isRequireAlternate" label="备用链接">
        <n-text depth="3">{{ alternatePlaceholder }}</n-text>
      </n-form-item>
      <n-form-item :show-require-mark="isRequireAlternate" label="链接" path="alternateLinkType">
        <component
          :is="componentTag"
          v-model:value="formData.alternateLinkType"
          :options="options"
          :disabled="isDisabled"
          placeholder="请选择链接"
          check-strategy="child"
          clearable
          @update:value="handleChangeLandingType"
        />
      </n-form-item>
      <n-form-item
        v-if="isLinkContent"
        :show-require-mark="isRequireAlternate"
        label="落地"
        path="alternateLinkContent"
      >
        <template v-if="isLinkContentInput">
          <n-space align="center">
            <n-input
              v-model:value="formData.alternateLinkContent"
              :maxlength="255"
              :placeholder="linkContentPlaceholder"
              clearable
              @blur="handleChangeLinkContent"
            />
            <n-tooltip placement="left">
              <template #trigger>
                <x-icon name="icon-063" />
              </template>
              {{ linkContentPlaceholder }}
            </n-tooltip>
          </n-space>
        </template>
        <template v-else>
          <n-space v-if="formData.alternateLinkContent">
            <n-tag type="info" closable @close="handleLandingRemove">
              <n-ellipsis style="max-width: 149px">
                {{ productInfo }}
              </n-ellipsis>
            </n-tag>
            <x-button type="primary" tertiary @click="drawerVisible = true">编辑</x-button>
          </n-space>
          <x-button v-else @click="drawerVisible = true">请选择落地值</x-button>
        </template>
      </n-form-item>
    </x-form>
    <template #footer>
      <x-button type="primary" ghost @click="handleCancel">取消</x-button>
      <x-button type="primary" @click="handleSubmit">确定</x-button>
    </template>
  </x-drawer>

  <x-landing-select
    v-if="drawerVisible"
    v-model:visible="drawerVisible"
    v-model:value="formData.alternateLinkContent"
    :tabs="landingTabs"
    :filters="landingFilter"
    @update:value="handleLandingChange"
  />
</template>

<script lang="ts">
  import { computed, defineComponent, h, nextTick, reactive, ref, toRefs, watch } from 'vue'
  import {
    NCascader,
    NFormItem,
    NInput,
    NTag,
    NSelect,
    NTooltip,
    NSpace,
    NEllipsis,
    NText,
    NA,
    useMessage
  } from 'naive-ui'
  import { XForm, XDrawer, XButton, XLandingSelect, XIcon } from '@/components'
  import { useDictionary } from '@/hooks'
  import { useStore } from '@/store'
  import { useRoute } from 'vue-router'
  import { isBms } from '@/utils/is'

  export default defineComponent({
    name: 'XLandingLive',
    components: {
      NFormItem,
      NInput,
      NText,
      NA,
      NTag,
      NEllipsis,
      NSpace,
      NTooltip,
      NSelect,
      NCascader,
      XIcon,
      XForm,
      XDrawer,
      XButton,
      XLandingSelect
    },
    props: {
      visible: {
        type: Boolean,
        default: false
      },
      type: {
        type: [Number, String],
        default: null
      },
      model: {
        type: Object,
        default: () => {}
      },
      // 是否为聚合页落地选择
      isGroup: {
        type: Boolean,
        default: false
      },
      // 备用可配置的落地信息
      options: {
        type: Array,
        default: () => []
      }
    },
    emits: ['update:visible', 'update:model', 'close'],
    setup($props, { emit: $emit }) {
      const $message = useMessage()
      const formRef: any = ref(null)
      const $store = useStore()
      const $route = useRoute()
      const $dictionary = useDictionary()
      $dictionary.get('LIVE_OPTIONS')
      const $state: any = reactive({
        ...toRefs($props),
        // 商家后台
        isBms,
        drawerVisible: false,
        liveVisible: $props.visible,
        formData: {
          ...$props.model,
          alternateLinkType: $props.model.alternateLinkType || null,
          alternateLinkContent: $props.model.alternateLinkContent || null,
          channelsId: $props.model.channelsId || null
        },
        // 使用下拉选择还是多级联动
        componentTag: computed(() => {
          if ($state.isBms) {
            return h(NSelect)
          } else {
            return h(NCascader)
          }
        }),
        // 字典
        dictionary: computed(() => $store.getters.dictionary),
        // 是否需要配置linkContent
        isRequireLinkContent: computed(() => [19, 20].includes($state.type)),
        // 备用链接是否必填
        isRequireAlternate: computed(() => $state.type !== 21),
        linkContentPlaceholder: computed(() => {
          switch ($state.formData?.linkType) {
            case 14:
              return '请输入小程序绝对路径，以/开头'
            case 15:
              return '请输入公众号绝对路径，以https://mp.weixin.qq.com/开头'
            default:
              return '请输入落地内容'
          }
        }),
        drawerTitle: computed(() => {
          return $dictionary.find($props.type, 'LIVE_OPTIONS')
        }),
        // 备用地址描述
        alternatePlaceholder: computed(() => {
          switch ($props.type) {
            default:
            case 19:
              return '当“视频ID”丢失时，用户点击组件时将会打开备用路径。'
            case 20:
              return '当“活动ID”丢失时，用户点击组件时将会打开备用路径。'
            case 21:
              return '当直播状态为“直播结束”时，用户点击组件时将会打开备用路径；不配置则会跳转到最近一场直播的结束页。'
            case 22:
              return '当“预约被取消了或者已用”时，用户点击组件时将会打开备用路径。'
          }
        }),
        linkContentName: computed(() => {
          switch ($props.type) {
            default:
            case 19:
              return '视频ID'
            case 20:
              return '活动ID'
          }
        }),
        linkContentExpression: computed(() => {
          switch ($props.type) {
            default:
            case 19:
              return 'export/'
            case 20:
              return 'event/'
          }
        }),
        placeholderName: computed(() => {
          return `请输入视频号以“${$state.linkContentExpression}”开头的${$state.linkContentName}，可在视频号助手获取`
        }),
        rules: {
          linkContent: {
            required: true,
            validator(rule: any, value: string) {
              if (value) {
                if (
                  ($props.type === 19 && /^export\//gi.test(value)) ||
                  ($props.type === 20 && /^event\//gi.test(value))
                ) {
                  return true
                } else {
                  return new Error('请输入正确的视频相关地址')
                }
              } else {
                return new Error('请输入视频相关地址')
              }
            },
            trigger: 'blur'
          },
          channelsId: {
            required: true,
            validator(rule: any, value: string) {
              if (value) {
                if (/^sph/gi.test(value)) {
                  return true
                } else {
                  return new Error('请输入正确的视频号ID，以“sph”开头的id，可在视频号助手获取')
                }
              } else {
                return new Error('请输入视频号ID，以“sph”开头的id，可在视频号助手获取')
              }
            },
            trigger: 'blur'
          }
        },
        // 是否需要配置详情的落地枚举值
        isLinkContent: computed(() => [1, 2, 14, 15, 16, 19, 20, 21, 22].includes($state.formData.alternateLinkType)),
        // 需要输入框的落地枚举值
        isLinkContentInput: computed(() => [14, 15].includes($state.formData.alternateLinkType)),
        // 联动选择禁用逻辑
        isDisabled: computed(() => {
          return $state.isBms
            ? !!$state.formData.alternateLinkContent
            : [1, 2, 16].includes($state.formData.alternateLinkType)
            ? !!$state.formData.alternateLinkContent
            : false
        }),
        // 过滤掉不可被选择的落地
        landingFilter: computed(() => {
          return $route.name === 'DecorationEdit' ? [$route.query.id] : []
        }),
        landingTabs: computed(() => {
          if ($state.isGroup) {
            // 商家聚合页需要支持两种选择
            switch ($state.formData.alternateLinkType) {
              case 1:
                return ['group', 'pages']
              case 2:
                return ['product']
              case 16:
                return ['advertising']
              default:
                return ['group', 'pages', 'product', 'advertising']
            }
          } else {
            // 业务后台和商家普通微页面，仅需要一种即可
            return $state.formData.alternateLinkType === 1 ? ['pages'] : ['product']
          }
        }),
        productInfo: computed(() => {
          const product = $state.formData.alternateProductInfo
          const productInfo = []
          if (product) {
            switch (product.linkType) {
              case 2:
                productInfo.push('商品')
                break
              case 16:
                productInfo.push('推广页')
                break
              case 1:
                // 1,2微页面；3-聚合页
                productInfo.push(product.type === 3 ? '聚合页' : '微页面')
                break
              default:
                break
            }
            productInfo.push(product.productName)
          }
          return productInfo.join(' | ')
        })
      })

      // watch
      watch(
        () => $props.visible,
        (value: boolean) => {
          $state.liveVisible = value
          if (value) {
            $state.formData = {
              ...$props.model,
              alternateLinkType: $props.model.alternateLinkType || null,
              alternateLinkContent: $props.model.alternateLinkContent || null
            }
          }
        }
      )

      // 取消操作
      const handleCancel = () => {
        $state.liveVisible = false
        $emit('update:visible', false)
        $emit('close')
      }

      // 校验落地类型与落地数据
      const rulesLinkType = () => {
        const { alternateLinkContent, alternateLinkType } = $state.formData
        // 必须配置落地数据
        if ($state.isRequireAlternate) {
          if (alternateLinkType) {
            return !([1, 2, 14, 15, 16].includes(alternateLinkType) && !alternateLinkContent)
          } else {
            return false
          }
        }
        if ([1, 2, 14, 15, 16].includes(alternateLinkType) && !alternateLinkContent) {
          return false
        }
        return !([15].includes(alternateLinkType) && !/^https:\/\/mp.weixin.qq.com/gi.test(alternateLinkContent))
      }

      // 删除选中的落地数据
      const handleLandingRemove = () => {
        $state.formData.alternateLinkContent = null
        $state.formData.alternateProductInfo = null
      }

      // 切换落地类型
      const handleChangeLandingType = () => {
        handleLandingRemove()
        // 微页面、商品
        if ([1, 2, 16].includes($state.formData.alternateLinkType)) {
          nextTick(() => {
            $state.drawerVisible = true
          })
        }
      }

      // 落地链接切换处理
      const handleChangeLinkContent = () => {
        const { alternateLinkContent, alternateLinkType } = $state.formData
        switch (alternateLinkType) {
          case 14:
            if (!alternateLinkContent) {
              return $message.warning('请输入正确的小程序路径')
            } else {
              let value = alternateLinkContent.replace(/\.html/gi, '')
              if (!/^\//.test(value)) {
                value = `/${value}`
              }
              $state.formData.alternateLinkContent = value
            }
            break
          case 15:
            if (!/^https:\/\/mp.weixin.qq.com/gi.test(alternateLinkContent)) {
              $state.formData.alternateLinkContent = null
              return $message.warning('请输入正确的公众号链接地址')
            }
            break
        }
      }

      // 选择落地数据
      const handleLandingChange = (id: string | number, item: any, currentTab: string) => {
        let productInfo
        // console.log(item)
        switch (currentTab) {
          case 'group':
          case 'pages':
            productInfo = {
              linkType: 1,
              type: item.type,
              linkContent: item.id,
              productName: item.title
            }
            break
          case 'product':
            productInfo = {
              linkType: 2,
              linkContent: item.id,
              productName: item.productTitle
            }
            break
          case 'advertising':
            productInfo = {
              linkType: 16,
              linkContent: item.id,
              productName: item.pageName
            }
            break
          default:
            productInfo = {
              linkType: 1,
              linkContent: item.id,
              productName: item.title
            }
            break
        }
        $state.formData.alternateProductInfo = productInfo
      }

      // 确定
      const handleSubmit = () => {
        formRef.value.validate((errors: []) => {
          if (!errors) {
            if (rulesLinkType()) {
              $emit('update:model', $state.formData)
              handleCancel()
            } else {
              $message.warning('请配置备用链接')
            }
          } else {
            $message.warning('验证失败，请填写完整信息')
          }
        })
      }

      return {
        ...toRefs($state),
        formRef,
        handleCancel,
        handleSubmit,
        handleChangeLandingType,
        handleChangeLinkContent,
        handleLandingChange,
        handleLandingRemove
      }
    }
  })
</script>

<style></style>
